/**
 * Security Service - 安全和加密服务
 * 为 IntelliMark 提供API密钥加密、数据保护和安全存储功能
 */

import { safeStorage } from 'electron'
import { createHash, randomBytes, createCipheriv, createDecipheriv } from 'crypto'
import Store from 'electron-store'

export interface SecurityConfig {
  enableEncryption: boolean
  encryptionKey?: string
  keyDerivationRounds: number
  useHardwareSecurity: boolean
  dataRetentionDays: number
  auditLogging: boolean
}

export interface EncryptedData {
  data: string
  iv: string
  salt: string
  algorithm: string
  timestamp: number
}

export interface SecurityAuditLog {
  id: string
  timestamp: number
  operation: 'encrypt' | 'decrypt' | 'store' | 'retrieve' | 'delete' | 'export' | 'import'
  resource: string
  userId?: string
  success: boolean
  error?: string
  metadata?: Record<string, any>
}

export class SecurityService {
  private store: Store
  private config: SecurityConfig
  private masterKey: string | null = null
  private auditLogs: SecurityAuditLog[] = []

  constructor(config?: Partial<SecurityConfig>) {
    this.store = new Store({
      name: 'security',
      defaults: {
        config: {
          enableEncryption: true,
          keyDerivationRounds: 100000,
          useHardwareSecurity: true,
          dataRetentionDays: 365,
          auditLogging: true
        },
        auditLogs: [],
        encryptedKeys: {}
      }
    })

    this.config = { ...this.store.get('config') as SecurityConfig, ...config }
    this.auditLogs = this.store.get('auditLogs') as SecurityAuditLog[] || []

    // 初始化主密钥
    this.initializeMasterKey()
  }

  /**
   * 初始化主密钥
   */
  private async initializeMasterKey(): Promise<void> {
    try {
      // 尝试从安全存储中获取主密钥
      if (this.config.useHardwareSecurity && safeStorage.isEncryptionAvailable()) {
        const storedKey = this.store.get('masterKey') as string
        if (storedKey) {
          this.masterKey = safeStorage.decryptString(Buffer.from(storedKey, 'base64')).toString()
        }
      }

      // 如果没有主密钥，生成一个新的
      if (!this.masterKey) {
        this.masterKey = this.generateMasterKey()
        await this.storeMasterKey()
      }

      console.log('Master key initialized successfully')
    } catch (error) {
      console.error('Failed to initialize master key:', error)
      this.masterKey = this.generateFallbackKey()
    }
  }

  /**
   * 生成主密钥
   */
  private generateMasterKey(): string {
    return randomBytes(32).toString('hex')
  }

  /**
   * 生成备用密钥
   */
  private generateFallbackKey(): string {
    const machineId = require('os').hostname() + require('os').platform()
    return createHash('sha256').update(machineId + Date.now()).digest('hex')
  }

  /**
   * 安全存储主密钥
   */
  private async storeMasterKey(): Promise<void> {
    if (!this.masterKey) return

    try {
      if (this.config.useHardwareSecurity && safeStorage.isEncryptionAvailable()) {
        const encrypted = safeStorage.encryptString(this.masterKey)
        this.store.set('masterKey', encrypted.toString('base64'))
      } else {
        // 如果硬件安全不可用，使用软件加密
        const encrypted = this.encrypt(this.masterKey, 'system_key_protection')
        this.store.set('masterKey', JSON.stringify(encrypted))
      }
    } catch (error) {
      console.error('Failed to store master key:', error)
      throw error
    }
  }

  /**
   * 加密数据
   */
  public encrypt(data: string, additionalKey?: string): EncryptedData {
    if (!this.config.enableEncryption) {
      return {
        data: Buffer.from(data).toString('base64'),
        iv: '',
        salt: '',
        algorithm: 'none',
        timestamp: Date.now()
      }
    }

    try {
      const key = this.deriveKey(additionalKey)
      const iv = randomBytes(16)
      const cipher = createCipheriv('aes-256-gcm', key, iv)

      let encrypted = cipher.update(data, 'utf8', 'hex')
      encrypted += cipher.final('hex')

      const authTag = cipher.getAuthTag()

      const result: EncryptedData = {
        data: encrypted,
        iv: iv.toString('hex'),
        salt: this.generateSalt(),
        algorithm: 'aes-256-gcm',
        timestamp: Date.now()
      }

      // 存储认证标签
      result.data = result.data + ':' + authTag.toString('hex')

      this.logAudit('encrypt', 'data', true, { algorithm: result.algorithm, timestamp: result.timestamp })

      return result
    } catch (error) {
      this.logAudit('encrypt', 'data', false, { error: error instanceof Error ? error.message : 'Unknown error' })
      throw new Error(`Encryption failed: ${error instanceof Error ? error.message : 'Unknown error'}`)
    }
  }

  /**
   * 解密数据
   */
  public decrypt(encryptedData: EncryptedData, additionalKey?: string): string {
    if (!this.config.enableEncryption || encryptedData.algorithm === 'none') {
      return Buffer.from(encryptedData.data, 'base64').toString('utf8')
    }

    try {
      const key = this.deriveKey(additionalKey)
      const iv = Buffer.from(encryptedData.iv, 'hex')

      // 分离数据和认证标签
      const [data, authTagHex] = encryptedData.data.split(':')
      const authTag = Buffer.from(authTagHex, 'hex')

      const decipher = createDecipheriv('aes-256-gcm', key, iv)
      decipher.setAuthTag(authTag)

      let decrypted = decipher.update(data, 'hex', 'utf8')
      decrypted += decipher.final('utf8')

      this.logAudit('decrypt', 'data', true, { algorithm: encryptedData.algorithm })

      return decrypted
    } catch (error) {
      this.logAudit('decrypt', 'data', false, { error: error instanceof Error ? error.message : 'Unknown error' })
      throw new Error(`Decryption failed: ${error instanceof Error ? error.message : 'Unknown error'}`)
    }
  }

  /**
   * 安全存储API密钥
   */
  public async storeApiKey(provider: string, apiKey: string): Promise<void> {
    try {
      const encrypted = this.encrypt(apiKey, provider)
      const encryptedKeys = this.store.get('encryptedKeys') as Record<string, EncryptedData> || {}
      encryptedKeys[provider] = encrypted
      this.store.set('encryptedKeys', encryptedKeys)

      this.logAudit('store', `api_key_${provider}`, true)
    } catch (error) {
      this.logAudit('store', `api_key_${provider}`, false, { error: error instanceof Error ? error.message : 'Unknown error' })
      throw error
    }
  }

  /**
   * 获取API密钥
   */
  public async getApiKey(provider: string): Promise<string | null> {
    try {
      const encryptedKeys = this.store.get('encryptedKeys') as Record<string, EncryptedData> || {}
      const encrypted = encryptedKeys[provider]

      if (!encrypted) {
        return null
      }

      const apiKey = this.decrypt(encrypted, provider)
      this.logAudit('retrieve', `api_key_${provider}`, true)

      return apiKey
    } catch (error) {
      this.logAudit('retrieve', `api_key_${provider}`, false, { error: error instanceof Error ? error.message : 'Unknown error' })
      return null
    }
  }

  /**
   * 删除API密钥
   */
  public async deleteApiKey(provider: string): Promise<void> {
    try {
      const encryptedKeys = this.store.get('encryptedKeys') as Record<string, EncryptedData> || {}
      delete encryptedKeys[provider]
      this.store.set('encryptedKeys', encryptedKeys)

      this.logAudit('delete', `api_key_${provider}`, true)
    } catch (error) {
      this.logAudit('delete', `api_key_${provider}`, false, { error: error instanceof Error ? error.message : 'Unknown error' })
      throw error
    }
  }

  /**
   * 验证数据完整性
   */
  public verifyIntegrity(data: string, expectedHash: string): boolean {
    const actualHash = this.calculateHash(data)
    return actualHash === expectedHash
  }

  /**
   * 计算数据哈希
   */
  public calculateHash(data: string): string {
    return createHash('sha256').update(data).digest('hex')
  }

  /**
   * 生成安全随机字符串
   */
  public generateSecureRandom(length: number = 32): string {
    return randomBytes(Math.ceil(length / 2)).toString('hex').substring(0, length)
  }

  /**
   * 检查密码强度
   */
  public checkPasswordStrength(password: string): {
    score: number
    feedback: string[]
    isStrong: boolean
  } {
    const feedback: string[] = []
    let score = 0

    // 长度检查
    if (password.length >= 12) {
      score += 2
    } else if (password.length >= 8) {
      score += 1
    } else {
      feedback.push('密码长度至少需要8个字符')
    }

    // 复杂度检查
    if (/[a-z]/.test(password)) score += 1
    else feedback.push('需要包含小写字母')

    if (/[A-Z]/.test(password)) score += 1
    else feedback.push('需要包含大写字母')

    if (/\d/.test(password)) score += 1
    else feedback.push('需要包含数字')

    if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) score += 2
    else feedback.push('需要包含特殊字符')

    // 常见密码检查
    const commonPasswords = ['password', '123456', 'qwerty', 'admin', 'letmein']
    if (commonPasswords.some(common => password.toLowerCase().includes(common))) {
      score -= 2
      feedback.push('不能使用常见密码')
    }

    return {
      score: Math.max(0, Math.min(10, score)),
      feedback,
      isStrong: score >= 7
    }
  }

  /**
   * 安全导出数据
   */
  public async exportSecureData(includeKeys: boolean = false): Promise<{
    timestamp: number
    version: string
    settings: any
    analytics?: any
    encryptedKeys?: Record<string, EncryptedData>
  }> {
    try {
      const exportData: any = {
        timestamp: Date.now(),
        version: '1.0.0',
        settings: this.store.get('settings')
      }

      if (includeKeys) {
        exportData.encryptedKeys = this.store.get('encryptedKeys')
      }

      this.logAudit('export', 'secure_data', true, { includeKeys })

      return exportData
    } catch (error) {
      this.logAudit('export', 'secure_data', false, { error: error instanceof Error ? error.message : 'Unknown error' })
      throw error
    }
  }

  /**
   * 安全导入数据
   */
  public async importSecureData(data: any, verifySignature: boolean = true): Promise<void> {
    try {
      // 验证数据格式
      if (!data.version || !data.timestamp) {
        throw new Error('Invalid export format')
      }

      // 导入设置
      if (data.settings) {
        this.store.set('settings', data.settings)
      }

      // 导入加密密钥（如果存在且被允许）
      if (data.encryptedKeys) {
        const existingKeys = this.store.get('encryptedKeys') as Record<string, EncryptedData> || {}
        const mergedKeys = { ...existingKeys, ...data.encryptedKeys }
        this.store.set('encryptedKeys', mergedKeys)
      }

      this.logAudit('import', 'secure_data', true, { version: data.version })
    } catch (error) {
      this.logAudit('import', 'secure_data', false, { error: error instanceof Error ? error.message : 'Unknown error' })
      throw error
    }
  }

  /**
   * 清理敏感数据
   */
  public async cleanupSensitiveData(): Promise<void> {
    try {
      // 清理旧的审计日志
      const cutoffTime = Date.now() - (this.config.dataRetentionDays * 24 * 60 * 60 * 1000)
      this.auditLogs = this.auditLogs.filter(log => log.timestamp > cutoffTime)
      this.store.set('auditLogs', this.auditLogs)

      // 清理临时数据
      this.store.delete('tempData')

      this.logAudit('delete', 'sensitive_data_cleanup', true)
    } catch (error) {
      this.logAudit('delete', 'sensitive_data_cleanup', false, { error: error instanceof Error ? error.message : 'Unknown error' })
    }
  }

  /**
   * 获取安全状态
   */
  public getSecurityStatus(): {
    encryptionEnabled: boolean
    hardwareSecurityAvailable: boolean
    masterKeyInitialized: boolean
    encryptedProvidersCount: number
    lastAuditLog?: SecurityAuditLog
    recommendations: string[]
  } {
    const encryptedKeys = this.store.get('encryptedKeys') as Record<string, EncryptedData> || {}
    const recommendations: string[] = []

    if (!this.config.enableEncryption) {
      recommendations.push('启用加密以保护敏感数据')
    }

    if (!this.config.useHardwareSecurity || !safeStorage.isEncryptionAvailable()) {
      recommendations.push('考虑启用硬件安全模块以获得更好的保护')
    }

    if (Object.keys(encryptedKeys).length === 0) {
      recommendations.push('没有存储的API密钥')
    }

    return {
      encryptionEnabled: this.config.enableEncryption,
      hardwareSecurityAvailable: safeStorage.isEncryptionAvailable(),
      masterKeyInitialized: !!this.masterKey,
      encryptedProvidersCount: Object.keys(encryptedKeys).length,
      lastAuditLog: this.auditLogs[this.auditLogs.length - 1],
      recommendations
    }
  }

  /**
   * 更新安全配置
   */
  public updateConfig(newConfig: Partial<SecurityConfig>): void {
    this.config = { ...this.config, ...newConfig }
    this.store.set('config', this.config)
  }

  /**
   * 获取审计日志
   */
  public getAuditLogs(limit?: number): SecurityAuditLog[] {
    const logs = [...this.auditLogs].sort((a, b) => b.timestamp - a.timestamp)
    return limit ? logs.slice(0, limit) : logs
  }

  // 私有方法

  private deriveKey(additionalKey?: string): Buffer {
    if (!this.masterKey) {
      throw new Error('Master key not initialized')
    }

    const salt = this.generateSalt()
    const keyMaterial = additionalKey ? this.masterKey + additionalKey : this.masterKey

    return createHash('sha256')
      .update(keyMaterial)
      .update(salt)
      .digest()
  }

  private generateSalt(): string {
    return randomBytes(16).toString('hex')
  }

  private logAudit(
    operation: SecurityAuditLog['operation'],
    resource: string,
    success: boolean,
    metadata?: Record<string, any>
  ): void {
    if (!this.config.auditLogging) return

    const log: SecurityAuditLog = {
      id: this.generateSecureRandom(8),
      timestamp: Date.now(),
      operation,
      resource,
      success,
      error: success ? undefined : metadata?.error,
      metadata
    }

    this.auditLogs.push(log)

    // 限制日志数量
    if (this.auditLogs.length > 1000) {
      this.auditLogs = this.auditLogs.slice(-1000)
    }

    this.store.set('auditLogs', this.auditLogs)
  }
}

// 导出单例实例
let securityServiceInstance: SecurityService | null = null

export function getSecurityService(config?: Partial<SecurityConfig>): SecurityService {
  if (!securityServiceInstance) {
    securityServiceInstance = new SecurityService(config)
  }
  return securityServiceInstance
}